package com.list88zhu.common.rxhttp.http.subscriber;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.util.Log;

import com.list88zhu.common.rxhttp.BaseApplication;
import com.list88zhu.common.rxhttp.http.BaseApi;
import com.list88zhu.common.rxhttp.http.HttpOnNextListener;
import com.list88zhu.common.rxhttp.http.entity.CookieEntity;
import com.list88zhu.common.rxhttp.http.exception.ApiException;
import com.list88zhu.common.rxhttp.http.exception.CodeException;
import com.list88zhu.common.rxhttp.http.exception.HttpResultException;
import com.list88zhu.common.rxhttp.tools.CookieDbUtil;
import com.list88zhu.common.rxhttp.tools.NetworkUtils;
import com.trello.rxlifecycle.components.support.RxAppCompatActivity;
import java.lang.ref.SoftReference;
import rx.Observable;
import rx.Subscriber;

/**
 * projectName rxretrofit
 * date 2017/6/21
 * description com.example.administrator.rxjavaretrofitsample.subscriber
 */

public class ProgressSubscriber<T> extends Subscriber<T> {
    /*是否弹框*/
    private boolean showProgress = true;
    /* 软引用回调接口*/
    private HttpOnNextListener mSubscriberOnNextListener;
    /*软引用防止内存泄露*/
    private SoftReference<RxAppCompatActivity> mActivity;
    /*加载框可自己定义*/
    protected ProgressDialog loadingDialog;
    /*请求数据*/
    private BaseApi api;

    public ProgressSubscriber(BaseApi api){
        this.api = api;
        this.mSubscriberOnNextListener = api.getListener();
        this.mActivity = new SoftReference<>(api.getRxAppCompatActivity());
        setShowProgress(api.isShowProgress());
        if(api.isShowProgress()){
            initProgressDialog(api.isCancel());
        }
    }

    private void initProgressDialog(boolean cancel){
        Context context = mActivity.get();
        if(loadingDialog == null && context != null){
            loadingDialog = new ProgressDialog(api.getRxAppCompatActivity());
            loadingDialog.setCancelable(cancel);
            if(cancel){
                loadingDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        if(mSubscriberOnNextListener != null){
                            mSubscriberOnNextListener.onCancel();
                        }
                        onCancelProgress();
                    }
                });
            }
        }
    }

    private void showProgressDialog(){
        if(!isShowProgress()) return;
        Context context = mActivity.get();
        if(loadingDialog == null || context == null ) return;
        loadingDialog.dismiss();
        if (!loadingDialog.isShowing()){
            loadingDialog.show();
        }
    }

    private void dismissProgressDialog(){
        if(!isShowProgress()) return;
        if (loadingDialog != null && loadingDialog.isShowing()){
            loadingDialog.dismiss();
        }
    }

    public void onCancelProgress(){
        if(!this.isUnsubscribed()){
            this.unsubscribe();
        }
    }

    private boolean isShowProgress(){
        return showProgress;
    }

    @Override
    public void onStart() {
        showProgressDialog();
        //缓存并有网络
        if(api.isCache() && NetworkUtils.isNetworkAvailable(BaseApplication.getInstance().getApplicationContext())){
            //获取缓存
            Log.i("cache", "intercept: 1 " + api.getUrl());
            CookieEntity cookie = CookieDbUtil.getInstance().queryCookieBy(api.getUrl());
            if(cookie != null){
                long time = cookie.getTime();
                if((System.currentTimeMillis() - time)/1000 < api.getCookieNetworkTime()){
                    if(mSubscriberOnNextListener != null){
                        mSubscriberOnNextListener.onNext(cookie.getResulte(), api.getMethod()+"  cookie");
                    }
                    onCompleted();
                    unsubscribe();
                }
            }
        }
    }

    @Override
    public void onCompleted() {
        dismissProgressDialog();
    }

    @Override
    public void onError(final Throwable e) {
        dismissProgressDialog();
        //需要缓存并本地有缓存才返回
        if(api.isCache()){
            Observable.just(api.getUrl()).subscribe(new Subscriber<String>(){

                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(String s) {
                    //获取缓存
                    Log.i("cache", "intercept: 2 " + s);
                    CookieEntity cookie = CookieDbUtil.getInstance().queryCookieBy(s);
                    if(cookie == null){
                        if(mSubscriberOnNextListener != null){
                            mSubscriberOnNextListener.onError((ApiException) e);
                        }
                    }
                    int time = (int) ((System.currentTimeMillis() - cookie.getTime()) / 1000);
                    if(time < api.getCookieNoNetworkTime()){
                        if(mSubscriberOnNextListener != null){
                            mSubscriberOnNextListener.onNext(cookie.getResulte(), api.getMethod());
                        }
                    }else{
                        CookieDbUtil.getInstance().deleteCookie(cookie);
                        throw new HttpResultException("网络错误");
                    }
                }
            });
        }else{
            errorDo(e);
        }
    }

    @Override
    public void onNext(T t) {
        if(api.isCache()){
            CookieDbUtil dbUtils = CookieDbUtil.getInstance();
            CookieEntity cookie = dbUtils.queryCookieBy(api.getUrl());
            long time = System.currentTimeMillis();
            /*保存和更新本地数据*/
            if(cookie == null){
                cookie = new CookieEntity(api.getUrl(), t.toString(), time);
                dbUtils.saveCookie(cookie);
            }else{
                cookie.setResulte(t.toString());
                cookie.setTime(time);
                dbUtils.updateCookie(cookie);
            }
        }
        if(mSubscriberOnNextListener != null){
            mSubscriberOnNextListener.onNext((String)t, api.getMethod());
        }
    }

    public void setShowProgress(boolean showProgress) {
        this.showProgress = showProgress;
    }

    /*错误统一处理*/
    private void errorDo(Throwable e) {
        Context context = mActivity.get();
        if (context == null) return;
        HttpOnNextListener httpOnNextListener = mSubscriberOnNextListener;
        if(httpOnNextListener == null) return;
        if(e instanceof ApiException){
            httpOnNextListener.onError((ApiException) e);
        }else if(e instanceof HttpResultException){
            HttpResultException exception=(HttpResultException)e;
            httpOnNextListener.onError(new ApiException(exception, CodeException.RUNTIME_ERROR,exception.getMessage()));
        }else{
            httpOnNextListener.onError(new ApiException(e, CodeException.UNKNOWN_ERROR,e.getMessage()));
        }
    }
}
